package com.lst.api.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.lst.api.constant.ApplyTypeEnum;
import com.lst.api.constant.RedisKeysConstant;
import com.lst.api.entity.*;
import com.lst.api.exception.RequestParamErrorException;
import com.lst.api.service.*;
import com.lst.api.utils.SerialNumberUtils;
import com.lst.api.vo.*;
import com.lst.api.vo.request.LoanApplyRequest;
import com.lst.api.vo.response.LoanApplyResponse;
import com.lst.api.vo.response.LoanApplySelectDataResponse;
import com.lst.tools.redis.service.IRedisService;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @author: Frank
 * @date: 2019/12/30 14:16
 * @version: V1.0
 */
@Service
public class LoanApplyService implements ILoanApplyService {

    @Autowired
    private IApplyInfoService applyInfoService;
    @Autowired
    private IPersonInfoService personInfoService;
    @Autowired
    private IAssetsCarInfoService assetsCarInfoService;
    @Autowired
    private IAssetsCreditInfoService assetsCreditInfoService;
    @Autowired
    private IAssetsHouseInfoService assetsHouseInfoService;
    @Autowired
    private ICompanyInfoService companyInfoService;
    @Autowired
    private ILoanInfoService loanInfoService;
    @Autowired
    private ITaxInfoService taxInfoService;
    @Autowired
    private IWorkCompanyInfoService workCompanyInfoService;
    @Autowired
    private IRedisService redisService;
    @Autowired
    private IBusinessPlaceService businessPlaceService;
    @Autowired
    private ICompanyTypeService companyTypeService;
    @Autowired
    private IIndustryTypeService industryTypeService;
    @Autowired
    private ILoanBankService loanBankService;
    @Autowired
    private ILoanPurposeService loanPurposeService;
    @Autowired
    private IOverdueService overdueService;
    @Autowired
    private IResideTypeService resideTypeService;
    @Autowired
    private ITaxLevelService taxLevelService;
    @Autowired
    private ICarBrandService carBrandService;

    @Override
    public String apply(long userId, LoanApplyRequest loanApplyRequest) {
        String applyNo = loanApplyRequest.getApplyNo();
        if (StringUtils.isBlank(applyNo)) {
            applyNo = SerialNumberUtils.generateNo(userId, SerialNumberUtils.TYPE_APPLY_NO);
        }
        personInfoService.saveOrUpdate(userId, applyNo, loanApplyRequest.getPersonInfo());
        ApplyInfoVo applyInfoVo = loanApplyRequest.getApplyInfo();
        applyInfoService.saveOrUpdate(userId, applyNo, applyInfoVo);
        assetsCarInfoService.saveOrUpdate(userId, applyNo, loanApplyRequest.getAssetsCarInfo());
        assetsCreditInfoService.saveOrUpdate(userId, applyNo, loanApplyRequest.getAssetsCreditInfo());
        assetsHouseInfoService.saveOrUpdate(userId, applyNo, loanApplyRequest.getAssetsHouseInfo());
        String applyType = applyInfoVo.getApplyType();
        if (ApplyTypeEnum.PERSON.getKey().equals(applyType)) {
            workCompanyInfoService.saveOrUpdate(userId, applyNo, loanApplyRequest.getWorkCompanyInfo());
        }
        companyInfoService.saveOrUpdate(userId, applyNo, loanApplyRequest.getCompanyInfo(), loanApplyRequest.getTaxInfoList());
        loanInfoService.saveOrUpdate(userId, applyNo, loanApplyRequest.getLoanInfoList());
        return applyNo;
    }

    @Override
    public boolean idCardNoIsExist(String idCardNo) {
        return personInfoService.idCardNoIsExist(idCardNo);
    }

    @Override
    public LoanApplyResponse getInfoByIdCardNo(String idCardNo) {
        PersonInfo personInfo = personInfoService.getByIdCardNo(idCardNo);
        if (personInfo == null) {
            return null;
        }
        LoanApplyResponse loanApplyResponse = new LoanApplyResponse();
        loanApplyResponse.setApplyNo(personInfo.getApplyNo());
        loanApplyResponse.setPromoUserId(personInfo.getPromoUserId());
        loanApplyResponse.setPersonInfo(new PersonInfoVo(personInfo));
        String applyNo = personInfo.getApplyNo();
        ApplyInfo applyInfo = applyInfoService.getByApplyNo(applyNo);
        loanApplyResponse.setApplyInfo(new ApplyInfoVo(applyInfo));
        if (ApplyTypeEnum.PERSON.getKey().equals(applyInfo.getApplyType())) {
            WorkCompanyInfo workCompanyInfo = workCompanyInfoService.getByApplyNo(applyNo);
            loanApplyResponse.setWorkCompanyInfo(workCompanyInfo == null ? null : new WorkCompanyInfoVo(workCompanyInfo));
        }
        AssetsCarInfo assetsCarInfo = assetsCarInfoService.getByApplyNo(applyNo);
        loanApplyResponse.setAssetsCarInfo(assetsCarInfo == null ? null : new AssetsCarInfoVo(assetsCarInfo));
        AssetsCreditInfo assetsCreditInfo = assetsCreditInfoService.getByApplyNo(applyNo);
        loanApplyResponse.setAssetsCreditInfo(assetsCreditInfo == null ? null : new AssetsCreditInfoVo(assetsCreditInfo));
        AssetsHouseInfo assetsHouseInfo = assetsHouseInfoService.getByApplyNo(applyNo);
        loanApplyResponse.setAssetsHouseInfo(assetsHouseInfo == null ? null : new AssetsHouseInfoVo(assetsHouseInfo));
        CompanyInfo companyInfo = companyInfoService.getByApplyNo(applyNo);
        loanApplyResponse.setCompanyInfo(companyInfo == null ? null : new CompanyInfoVo(companyInfo));
        List<LoanInfo> loanInfoList = loanInfoService.listByApplyNo(applyNo);
        if (CollectionUtils.isNotEmpty(loanInfoList)) {
            List<LoanInfoVo> loanInfoVoList = loanInfoList.stream().map(LoanInfoVo::new).collect(Collectors.toList());
            loanApplyResponse.setLoanInfoList(loanInfoVoList);
        }
        List<TaxInfo> taxInfoList = taxInfoService.listByApplyNo(applyNo);
        if (CollectionUtils.isNotEmpty(taxInfoList)) {
            List<TaxInfoVo> taxInfoVoList = taxInfoList.stream().map(TaxInfoVo::new).collect(Collectors.toList());
            loanApplyResponse.setTaxInfoList(taxInfoVoList);
        }
        return loanApplyResponse;
    }

    @Override
    public LoanApplySelectDataResponse listAllSelectData() {
        try {
            String dataJson = redisService.get(RedisKeysConstant.LOAN_APPLY_SELECT_DATA);
            if (StringUtils.isNotBlank(dataJson)) {
                return JSON.parseObject(dataJson, new TypeReference<LoanApplySelectDataResponse>() {
                });
            }
        } catch (Exception e) {
        }
        LoanApplySelectDataResponse loanApplySelectDataResponse = new LoanApplySelectDataResponse();

        List<IsRentCodeAndNameVo> businessPlaceList = businessPlaceService.listBusinessPlace();
        loanApplySelectDataResponse.setBusinessPlaceList(businessPlaceList);

        List<IsInputCodeAndNameVo> companyTypeList = companyTypeService.listCompanyType();
        loanApplySelectDataResponse.setCompanyTypeList(companyTypeList);

        List<IsInputCodeAndNameVo> industryTypeList = industryTypeService.listIndustryType();
        loanApplySelectDataResponse.setIndustryTypeList(industryTypeList);

        List<IsInputCodeAndNameVo> loanBankList = loanBankService.listLoanBank();
        loanApplySelectDataResponse.setLoanBankList(loanBankList);

        List<IsInputCodeAndNameVo> loanPurposeList = loanPurposeService.listLoanPurpose();
        loanApplySelectDataResponse.setLoanPurposeList(loanPurposeList);

        List<IsInputCodeAndNameVo> overdueList = overdueService.listOverdue();
        loanApplySelectDataResponse.setOverdueList(overdueList);

        List<IsInputCodeAndNameVo> resideTypeList = resideTypeService.listResideType();
        loanApplySelectDataResponse.setResideTypeList(resideTypeList);

        List<CodeAndNameVo> taxLevelList = taxLevelService.listTaxLevel();
        loanApplySelectDataResponse.setTaxLevelList(taxLevelList);

        List<IsInputCodeAndNameVo> carBrandList = carBrandService.listCarBrandList();
        loanApplySelectDataResponse.setCarBrandList(carBrandList);
        try {
            redisService.set(RedisKeysConstant.LOAN_APPLY_SELECT_DATA, JSON.toJSONString(loanApplySelectDataResponse));
        } catch (Exception e) {
        }
        return loanApplySelectDataResponse;
    }
}
